#####################################################################
# Product:      KnowledgeEngine (Plone Edition)
#
# File:         MultipleAssessmentReport.py
#
# Copyright:    Copyright (c) 2005, Faulkner Technologies
#
# Author:       Brian Oliver
#
# Description:  This file defines the abstract MultipleAssessmentReport class, the 
#               base class of all Model reports that are generated from 
#               multiple assessments.  For example: Summary Reports
#               and Data Dumps.
#
# See Also:     Report, SingleAssessmentReport, AssessmentFilter,
#               AssessmentStorageService
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.Core import *
from Products.KnowledgeEngine.Report import Report, ReportInfo
from Products.KnowledgeEngine.Model.Model import Model
from Products.KnowledgeEngine.PropertyDefinition import *
from Products.KnowledgeEngine.PropertyTypes import *
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyStructures import *
from Products.KnowledgeEngine.EventDefinition import *

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from App.ImageFile import ImageFile
from Acquisition import *
from DateTime import DateTime

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## MultipleAssessmentReportInfo Class Definition
class MultipleAssessmentReportInfo(ReportInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return 'MultipleAssessmentReport'

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "MultipleAssessmentReport"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "multipleassessmentreport"

    #---------------------------------------------------------------#

    def isInstanceOf(self, className):
        """
            Returns if the class is an instance of the specified
            className, or implements the interface specified 
            by the className
        """

        return className == 'MultipleAssessmentReport' or ReportInfo.isInstanceOf(self, className)
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        ReportInfo.onConfigureProperties(self)
     
     #---------------------------------------------------------------#
 
    def onConfigureEvents(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific events using the EventReflection interface.

            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered

            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class events for reflection
        ReportInfo.onConfigureEvents(self)
    
    #---------------------------------------------------------------#

    def onConfigurePermissions(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific permission definitions.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """
        

        #initialise the super-class permissions for reflection
        ReportInfo.onConfigurePermissions(self)
        
    #---------------------------------------------------------------#

#####################################################################
## MultipleAssessmentReport Class Definition
class MultipleAssessmentReport(Report):
    """
        Base class for all KnowledgeEngine MultipleAssessmentReports
    """

    #---------------------------------------------------------------#

    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = MultipleAssessmentReportInfo()

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the Report"        
        
        Report.__init__(self, id, identity)

    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """

        #preform default onAfterInstanciation processing
        Report.onAfterInstanciation(self)
        
        ###print "DEBUG: MultipleAssessmentReport.onAfterInstanciation: Completed"
        
    #---------------------------------------------------------------#

    def getDefaultExitURL(self, request):
        """
            ABSTRACT: Returns the default URL to be used
            when exiting a report            
        """

        ###determine the exit URL (where to go if we close/cancel this report)
        portal = self.portal_url.getPortalObject()
        return '%s/assessmentexplorer' % (portal.absolute_url())
        
    #---------------------------------------------------------------#

    def isLockedModelRequired(self):
        """
            ABSTRACT: Returns if the report must have a locked model
            in order to be generated.
        """
        
        #normally this isn't required
        return false
        
    #---------------------------------------------------------------#

    def prepareDefaultWizardState(self, request, wizardState):
        """
            Prepares and adds any necessary additional
            state from the request to the wizard state.
            
            This method is called prior to initialise wizardState
            prior to generating a report and prior to attempting
            to collect wizard state from the wizard steps.
            
            You SHOULD capture any properties from the request HERE
            if you want to pass then to a report.

        """
        
        #get the session from the request
        session = request["SESSION"]

        #capture the current filter and place it in the wizard state
        #so we don't lose it when stepping through wizard steps
        wizardState.setPropertyValue("assessmentFilter", session.get('currentAssessmentFilter'))

    #---------------------------------------------------------------#

    def renderReport(self, request, wizardState, **args):
        """
            Renders the report content (called by Report.generate)
            
            NOTE: Override this method to perform specific
            report generation/rendering using the provided
            parameters
        """
    
        #get the assessment storage service... we'll need that to manage the assessment
        storageService = getAssessmentStorageService(self)

        #get the exitURL (will always be valid)
        exitURL = wizardState.getPropertyValue("exitURL")
        
        #get the repository the report is being opened from (may be None)
        openedFromRepositoryIdentity = wizardState.getPropertyValue("openedFromRepositoryIdentity")

        #get the current user that is rendering the report
        user = request["USER"]
    
        #get the session from the request
        session = request["SESSION"]
        
        #get the response from the request (weird I know, but that's where it lives in Zope)
        response = request["RESPONSE"]

        #get the assessment filter to use to filter out assessments from the session 
        #(this is typically set by the assessment explorer)
        assessmentFilter = wizardState.getPropertyValue("assessmentFilter")

        #add the parameters and assessment filter to the request
        request['ASSESSMENT_FILTER'] = assessmentFilter
        
        return eval("self.%s_report(self, REQUEST=request, **args)" % self.getClassInfo().getClassName())
        
    #---------------------------------------------------------------#
    
#####################################################################
## Class Initialisation
# (none)
